// HSS.AsyncResultT.cs
// ----------------------------------------------------------------------------
// Licensed under the MIT license
// http://www.opensource.org/licenses/mit-license.html
// ----------------------------------------------------------------------------
// HighSpeed-Solutions, LLC
// Copyright (c) 2001-2010
// ----------------------------------------------------------------------------
// File:       AsyncResultT.cs
// Author:     HSS\gbanta
// Created:    08/12/2010
// Modified:   12/04/2010
// ----------------------------------------------------------------------------
namespace HSS
{
	#region Using Directives
	using System;

	#endregion

	/// <summary>
	/// A generic implementation of <see cref="System.IAsyncResult"/> with a Type specified result
	/// </summary>
	/// <remarks>Courtesy of Jeffrey Richter (http://msdn.microsoft.com/msdnmag/issues/07/03/ConcurrentAffairs/)</remarks>
	/// <typeparam name="TResult">The type of the result object</typeparam>
	public class AsyncResult<TResult> : AsyncResultNoResult
	{
		// Field set when operation completes
		private TResult _result = default(TResult);

		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="asyncCallback">AsyncCallback</param>
		/// <param name="state">Object state</param>
		public AsyncResult(AsyncCallback asyncCallback, Object state)
			: base(asyncCallback, state)
		{
		}
		/// <summary>
		/// Indicate completion
		/// </summary>
		/// <param name="result">The results of the operation</param>
		/// <param name="completedSynchronously">Did it complete synchronously</param>
		public void SetAsCompleted(TResult result, Boolean completedSynchronously)
		{
			// Save the asynchronous operation's result
			_result = result;

			// Tell the base class that the operation completed 
			// sucessfully (no exception)
			base.SetAsCompleted(null, completedSynchronously);
		}

		/// <summary>
		/// Wait for operation to complete
		/// </summary>
		/// <returns>The TResult</returns>
		new public TResult EndInvoke()
		{
			base.EndInvoke(); // Wait until operation has completed 
			return _result;  // Return the result (if above didn't throw)
		}
	}

}